package com.zkh.myutils.utils;

import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

import com.zkh.myutils.io.log.Logger;

/**
 * 断言，用于验证数据
 * @author zkh
 */
public class Assert {
	
	/**
	 * 如果条件为true，则抛出message信息。
	 * @param arg 一个返回boolean值的逻辑
	 * @param message 如果arg参数返回true，则抛出message信息。
	 */
	public static void ifTrueThrow(boolean condition, String message) {
		ifTrueThrow(condition, message, IllegalArgumentException.class);
	}
	
	/**
	 * 如果条件为true，则抛出message信息。
	 * @param arg 一个返回boolean值的逻辑
	 * @param message 如果arg参数返回true，则抛出message信息。
	 * @param exceptionClass 指定异常类型
	 */
	public static void ifTrueThrow(boolean condition, String message, Class<? extends RuntimeException> exceptionClass) {
		try {
			//满足条件
			if(condition) throw (RuntimeException) exceptionClass.getConstructor(String.class).newInstance(message);
		} catch (Exception e) {
			Logger.error(e);
		}
	}
	
	/**
	 * 提供一个逻辑，如果返回true，则抛出message信息。
	 * @param arg 一个返回boolean值的逻辑
	 * @param message 如果arg参数返回true，则抛出message信息。
	 */
	public static void ifTrueThrow(BooleanSupplier supplier, String message) {
		ifTrueThrow(supplier.getAsBoolean(), message);
	}
	
	/**
	 * 提供一个逻辑，如果返回true，则抛出message信息。
	 * @param arg 一个返回boolean值的逻辑
	 * @param message 如果arg参数返回true，则抛出message信息。
	 * @param exceptionClass 指定异常类型
	 */
	public static void ifTrueThrow(BooleanSupplier supplier, String message, Class<? extends RuntimeException> exceptionClass) {
		ifTrueThrow(supplier.getAsBoolean(), message, exceptionClass);
	}
	
	/**
	 * 如果不为null，则执行
	 * @param value 要操作的值
	 * @param supplier 自定义处理逻辑
	 */
	public static <T> void doIfNotNull(T value, Consumer<T> consumer) {
		//不为空
		if(value!=null) {
			consumer.accept(value);
		}
	}
	
	/**
	 * 如果不为空（包括空字符串、空集合、空Map、空数组），则执行
	 * @param value 要操作的值
	 * @param supplier 自定义处理逻辑
	 */
	public static <T> void doIfNotEmpty(T value, Consumer<T> consumer) {
		//不为空
		if(!Utils.isEmpty(value)) {
			consumer.accept(value);
		}
	}
	
	/**
	 * 如果不为null，执行并返回一个值
	 * @param value 要操作的值
	 * @param supplier 自定义处理逻辑
	 */
	public static <M, N> N getIfNotNull(M value, Function<M, N> function) {
		return getIfNotNull(value, function, (N) null);
	}
	
	/**
	 * 如果不为null，执行并返回一个值
	 * @param value 要操作的值
	 * @param function 自定义处理逻辑
	 * @param dftVal 默认值，当value为null时返回
	 */
	public static <M, N> N getIfNotNull(M value, Function<M, N> function, N dftVal) {
		return getIfNotNull(value, function, (Supplier<N>) (()->dftVal));
	}
	
	/**
	 * 如果不为null，执行并返回一个值
	 * @param value 要操作的值
	 * @param function 自定义处理逻辑
	 * @param dftVal 默认值，当value为null时返回
	 */
	public static <M, N> N getIfNotNull(M value, Function<M, N> function, Supplier<N> supplier) {
		//不为null
		if(value!=null) {
			//获取值
			return function.apply(value);
		}
		return supplier.get();
	}
	
	/**
	 * 三目运算，扩展三目运算符
	 * @param condition 条件
	 * @param trueValue 为true的值
	 * @param falseValue 为false的值
	 * @return
	 */
	public static <T> T getIfElse(boolean condition, T trueValue, T falseValue) {
		return condition ? trueValue : falseValue;
	}
	
	/**
	 * 三目运算，扩展三目运算符
	 * @param condition 条件
	 * @param trueSupplier 为true的值
	 * @param falseSupplier 为false的值
	 * @return
	 */
	public static <T> T getIfElse(boolean condition, Supplier<T> trueSupplier, Supplier<T> falseSupplier) {
		return condition ? trueSupplier.get() : falseSupplier.get();
	}
	
	/**
	 * if判断，满足条件，执行一段代码
	 * @param condition 条件
	 * @param trueExec 为true时执行
	 */
	public static void doIfTrue(boolean condition, Execute trueExec) {
		doIfElse(condition, trueExec, ()->{});
	}
	/**
	 * 三目运算，扩展三目运算符
	 * @param condition 条件
	 * @param trueExec 为true时执行
	 * @param falseExec 为false时执行
	 */
	public static void doIfElse(boolean condition, Execute trueExec, Execute falseExec) {
		if(condition) {
			trueExec.apply();
		}else {
			falseExec.apply();
		}
	}
	
	/**
	 * 检查参数是否为null，如果为null，返回默认值
	 * @param obj 指定值
	 * @param dft 默认值，当指定值为null时返回
	 * @return
	 */
	public static <T> T getOrDefault(T obj, T dft) {
		return obj==null ? dft : obj;
	}
}
